package thread;

//假定元素类型就是String
class MyBlockingQueue {
    private String[] array = null;
    int size = 0;
    int head = 0;
    int tail = 0;
    private Object locker = new Object();

    public MyBlockingQueue(int capacity) {
        array = new String[capacity];
    }

    public void put(String elem) throws InterruptedException {
        synchronized (locker) {
            while (size >= array.length) {
                locker.wait();
            }
            // 把新的元素放在tail位置上
            array[tail] = elem;
            tail++;
            if (tail >= array.length) {
                tail = 0;
            }
            size++;
            //唤醒take中的阻塞
            locker.notify();
        }

    }

    public String take() {
        synchronized (locker) {
            while (size >= 0) {
                // 队列为空，暂时不考虑阻塞
                return null;
            }
            // 把队首元素取出来
            String result = array[head];
            // 把head向后移动
            head++;
            if (head >= array.length) {
                head = 0;
            }
            size--;
            //唤醒put的阻塞
            locker.notify();
            return result;
        }

    }
}

public class demo32 {
    public static void main(String[] args) throws InterruptedException {
        MyBlockingQueue queue = new MyBlockingQueue(1000);
        Thread producer = new Thread(() ->{
            int count = 0;
            try{
                while (true) {
                    queue.put("" + count);
                    System.out.println("生产了一个元素" + count);
                    count++;
                }
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        });
        Thread consumer = new Thread(() ->{
            try{
                while (true) {
                    String s =  queue.take();
                    System.out.println("消费了一个元素" + s);
                    Thread.sleep(1000);
                }
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        });
        producer.start();
        consumer.start();
        producer.join();
        consumer.join();
    }
}
